/**
 * 交易对手 业务组件 下拉列表结构
 * by zhangxinyue
 * create 2021-1-19
 */
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'dva';
import { LoadingOutlined, QuestionCircleOutlined } from '@ant-design/icons';
import { Form } from '@ant-design/compatible';
import '@ant-design/compatible/assets/index.css';
import { Input, Tooltip, message } from 'antd';
import { AutoCompleteC } from '../../form';
import debounce from 'lodash/debounce';
import { FormItemLayout, NoLableLayout } from '../../form/formPub';

const { Option } = AutoCompleteC;
// 给原有的DataSource添加label属性，值为原来的title
function transformOptions(dataSource) {
  return dataSource?.map((item) => {
    item.label = item.title;
    return item;
  });
}
class TradingCompanyC extends React.PureComponent {
  onSearchStatus = false; // 标记当前是否是查询状态

  flag = true; // “虚拟文本”标记

  doSearch = false; // 执行查询标记（解决前后两次搜索条件一致，导致因this.props.dataSource和nextProps.dataSource相等而无法展示搜索结果的情况）

  // 默认值
  static defaultProps = {
    title: '交易对手',
    initialValue: undefined,
    placeholder: '请输入交易对手',
    allowClear: true, // 允许清空
    helper: '',
    onChange: () => {},
    onRef: () => {}, // 本组件的引用
    dataIndex: undefined,
    loading: false,
    width: '100%',
    formItemLayout: FormItemLayout,
    dataType: 1, // 默认获取全市场交易对手
    labalWrap: false,
    InputValueSave: false,
    noQuery: false,
  };

  constructor(props) {
    super(props);
    this.state = {
      dataSource: [], // AutoComplete数据源，根据查询条件不同，从后台获取
      loading: false, // 当向后台请求数据时，loading为true
      tooltipInfo: '', // 鼠标移动到组件，展示当前选中项全称
    };

    // 绑定lodash的防抖函数，避免频繁搜索的情况
    this.handleSearch = debounce(this.handleSearch, 500);
  }

  // 调用接口，获取交易对手
  getTradingCompany = (value) => {
    this.setState({
      loading: true,
      tooltipInfo: '',
    });
    this.props.dispatch({
      type: 'tradingCompanyM/getTradingCompany',
      payload: {
        value: value ? value : '',
        dataType: this.props.dataType,
        isOtc: this.props.isOtc,
        scenesType: this.props.scenesType, // 组件场景类型，用于详情时根据ID回填值
      },
      callback: (e) => {
        const findSelect = e?.filter((item) => item.value === value);
        const tooltip = findSelect.length > 0 ? findSelect[0].title : value;
        this.setState({
          dataSource: e || [],
          loading: false,
          tooltipInfo: tooltip ? tooltip : '',
        });
      },
    });
  };

  componentDidMount() {
    // 父组件对本组件的引用
    this.props.onRef(this);
    console.log(this.props.noQuery, '********');
    if (!this.props.noQuery) this.getTradingCompany(this.props.initialValue);
  }

  // 非初始化状态下更改下拉选项(供父组件调用)(value值为'交易对手ID')
  setSelect = (value) => {
    // 设置form值，因为组件在没有选中值得状态下，也是有默认下拉得，所以这里对value设置得值不做限制
    const valueF = {};
    valueF[this.props.dataIndex] = value;
    this.props.form.setFieldsValue(valueF);
    this.getTradingCompany(value);
  };

  UNSAFE_componentWillReceiveProps(nextProps) {
    // 处理异步初始化场景
    const init = this.props.initialValue;
    const initN = nextProps.initialValue;
    if (JSON.stringify(init) !== JSON.stringify(initN)) {
      if (initN) {
        this.getTradingCompany(initN);
      } else {
        this.setSelect(null);
      }
    }
  }

  // 执行查询
  handleSearch = (value) => {
    // 为什么使用延时器？因为选词结束的时候search会比compositionend先一步触发，此时flag还未调整为true，故用setTimeout将其优先级滞后。
    setTimeout(() => {
      if (this.flag) {
        this.onSearchStatus = true;
        this.doSearch = true;
        this.getTradingCompany(value);
      }
    }, 0);
  };

  // 执行选中
  handleSelect = (value) => {
    this.onSearchStatus = false;
    const findSelect = this.state.dataSource.filter((item) => item.value === value);
    if (findSelect.length > 0) {
      // 对外抛出事件
      this.props.onChange(findSelect[0]);
      this.setState({
        tooltipInfo: findSelect[0].title,
      });
    }
  };

  // 选中 option，或 input 的 value 变化时，调用此函数
  // 这里主要处理allowClear设置为true时，点击clear按钮触发的change事件
  handleChange = (value) => {
    if (!value) {
      // 触发选项切换事件
      this.props.onChange(null);
      this.setState({
        tooltipInfo: '',
      });
    }
  };

  // 焦点离开事件
  onBlur = (e) => {
    const { InputValueSave } = this.props;
    /* 对于查询了信息，却未选中查询结果中的信息而焦点离开了，采用的策略是：清空。 */
    if (!InputValueSave) {
      if (this.onSearchStatus && e.target.value.trim() !== '') {
        message.info('未匹配，请重新输入查询条件。');
        // 清空输入内容
        const valueF = {};
        valueF[this.props.dataIndex] = null;
        this.props.form.setFieldsValue(valueF);
        // 触发选项切换事件
        this.props.onChange(null);
      }
    }
  };

  render() {
    const { labalWrap, styleRow, form, dataIndex, initialValue, placeholder, style, disabled, helper, allowClear, rules, width, title, formItemLayout } = this.props;
    const { loading } = this.state;
    const { getFieldDecorator } = form;
    return (
      <Form.Item
        colon={false}
        className={labalWrap ? 'labalWrap' : ''}
        style={style}
        labelCol={title ? formItemLayout.labelCol : NoLableLayout.labelCol}
        wrapperCol={title ? formItemLayout.wrapperCol : NoLableLayout.wrapperCol}
        label={
          helper ? (
            <span>
              {title}&nbsp;
              <Tooltip title={helper}>
                <QuestionCircleOutlined />
              </Tooltip>
            </span>
          ) : (
            <span>{title}</span>
          )
        }
      >
        <Tooltip title={this.state.tooltipInfo}>
          {getFieldDecorator(dataIndex, {
            initialValue,
            rules: rules ? rules : [],
          })(
            <AutoCompleteC
              flag={this.flag}
              style={styleRow ? styleRow : { width }}
              options={transformOptions(this.state.dataSource)}
              onSearch={this.handleSearch}
              onSelect={this.handleSelect}
              onChange={this.handleChange}
              placeholder={placeholder}
              allowClear={allowClear}
              dropdownClassName={this.theme}
              disabled={disabled}
            >
              <Input
                onCompositionStart={() => {
                  this.flag = false;
                }} // 处理“虚拟文本”
                onCompositionEnd={() => {
                  this.flag = true;
                }} // 处理“虚拟文本”
                onBlur={this.onBlur}
                suffix={<LoadingOutlined style={{ fontSize: loading ? 12 : 0, color: '#999' }} />}
              />
            </AutoCompleteC>,
          )}
        </Tooltip>
      </Form.Item>
    );
  }
}

// props默认值
TradingCompanyC.propsTypes = {
  form: PropTypes.object, // form对象
  title: PropTypes.string, // 显示名称
  dataIndex: PropTypes.string, // Form识别的Item ID
  initialValue: PropTypes.object, // 初始值（'交易对手ID'）
  helper: PropTypes.oneOfType([
    // 提示帮助信息
    PropTypes.string,
    PropTypes.element,
  ]),
  placeholder: PropTypes.string, // 占位符
  onChange: PropTypes.func, // 选项变更事件
  allowClear: PropTypes.boolean, // 设置允许清空输入内容
  dataSource: PropTypes.array, // 通过搜索条件，从后台获取的符合查询条件的数据源
  onRef: PropTypes.func, // 本组件的引用（可用来父组件调用内部方法）
  rules: PropTypes.array, // 校验规则
  formItemLayout: PropTypes.object, // {labelCol:{},wrapperCol:{}}
  disabled: PropTypes.boolean, // 是否禁用
  style: PropTypes.object, // 样式
  dataType: PropTypes.number, // 交易对手数据来源 1-全市场 2-交易对手模块 3-银行间交易对手
  noQuery: PropTypes.bool, // 首次不要请求 用于回填的时候
};

export default connect(({ tradingCompanyM }) => ({ tradingCompanyM }))(TradingCompanyC);
